/**
 * @Title: StringUtil.java
 * @Package com.bawei.common.utils
 * @Description: (描述该文件做什么)
 * @author Alex Lu
 * @date 2019年8月7日 下午5:37:23
 * @version V1.0
 */
package com.bawei.common.utils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;

/**
 * @ClassName: StringUtil
 * @Description: 字符串工具类
 * @author Alex Lu
 * @date 2019年8月7日 下午5:37:23
 *
 */
public class StringUtil {
	// 正则表达式
	public static final String PLACE_REGEX = "(\\d{7,8})";
	// 判断数字
	public static final String NUMBER_REGEX = "^[0-9]*$";
	// 判断邮箱
	public static final String EMAIL_REGEX = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
	// 判断手机号
	public static final String MOBILE_REGEX = "^1(3|4|5|7|8)\\d{9}$";

	// 判断多个空格的正则表达式
	public static final String BLANK_REGEX = "\\s*";

	public static final String NUMBER_POINT_REGEX = "^(\\-|\\+)?\\d+(\\.\\d+)?$";// "-([0-9]\\d*\\.?\\d*)|(0\\.\\d*[0-9])";

	public static final String HTTP_URL_REGEX = "(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]";

	public static final int IDENTITYCODE_OLD = 15; // 老身份证15位
	public static final int IDENTITYCODE_NEW = 18; // 新身份证18位

	public static final String HTML_REGEX = "<.+?>";

	public static final String IP_REGEX = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
			+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
			+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";

	public static final String IDENTITY_CODE_REGEX = "(^\\d{15}$)|(\\d{17}(?:\\d|x|X)$)";

	private StringUtil() {

	}

	/**
	 * 
	 * @Title: isEmpty
	 * @Description: 验证字符串是否为空，包括验证空格
	 * @param content
	 *            被验证的字符串
	 * @return
	 * @return boolean 符合为true，不符合为false
	 */
	public static boolean isEmpty(String content) {
		boolean flag = false;

		// 判断字符串是否为null和""
		if (content == null || "".equals(content)) {
			return flag;
		}
		if (content.length() <= 0) {
			return flag;
		}
		// 根据正则表达式进行匹配
		Pattern pattern = Pattern.compile(BLANK_REGEX);
		Matcher matcher = pattern.matcher(content);
		// 首先判断字符串是否为空格（1-n个空格）
		if (matcher.matches()) {
			return flag;
		}
		flag = true;
		return flag;
	}

	public static boolean isNotEmpty(String source) {
		boolean flag = false;
		if (source == null || "".equals(source) || source.length() <= 0) {
			return flag;
		}
		Pattern pattern = Pattern.compile(BLANK_REGEX);
		Matcher matcher = pattern.matcher(source);
		if (matcher.matches()) {
			return flag;
		}
		flag = true;
		return flag;
	}

	/**
	 * 
	 * @Title: validString
	 * @Description: 验证字符串是否为空，不包括空格
	 * @param str
	 * @return
	 * @return Boolean
	 */
	public static boolean validString(String str) {
		return str != null && str.length() > 0;

	}

	/**
	 * 
	 * @Title: validPhoneNum
	 * @Description: 验证手机号
	 * 
	 *               运营商号段如下：
	 *               中国联通号码：130、131、132、145（无线上网卡）、155、156、185（iPhone5上市后开放
	 *               ）、186、176（4G号段）、 175（2015年9月10日正式启用，暂只对北京、上海和广东投放办理）
	 *               中国移动号码：
	 *               134、135、136、137、138、139、147（无线上网卡）、150、151、152、157、158
	 *               、159、182、183、187、188、178
	 *               中国电信号码：133、153、180、181、189、177、173、149 虚拟运营商：170、1718、1719
	 *               手机号前3位的数字包括： 1 :1 2 :3,4,5,7,8 3 :0,1,2,3,4,5,6,7,8,9
	 * 
	 * @param phoneNum
	 * @return
	 * @return Boolean
	 */
	public static boolean isMobile(String phoneNum) {
		Boolean flag = false;
		String reg = MOBILE_REGEX;
		if (!isEmpty(phoneNum)) {
			return flag;
		}
		if (phoneNum.length() == 11) {
			Pattern pattern = Pattern.compile(reg);
			Matcher matcher = pattern.matcher(phoneNum);
			flag = matcher.matches();
		}
		return flag;

	}

	/**
	 * 
	 * @Title: isEmail
	 * @Description: 验证邮箱
	 * @param email
	 * @return
	 * @return Boolean
	 */
	public static boolean isEmail(String email) {
		Boolean flag = false;
		if (!isEmpty(email)) {
			return flag;
		}
		Pattern pattern = Pattern.compile(EMAIL_REGEX);
		Matcher matcher = pattern.matcher(email);
		flag = matcher.matches();
		return flag;

	}

	/**
	 * 
	 * @Title: isCharacter
	 * @Description: 判断是否全部为字母
	 * @param target
	 * @return
	 * @return boolean
	 */
	public static boolean isCharacter(String target) {
		String reg = "^[a-zA-Z]+$";
		if (target != null && !"".equals(target)) {
			Pattern pattern = Pattern.compile(reg);
			Matcher matcher = pattern.matcher(target);
			return matcher.matches();
		}
		return false;

	}

	/**
	 * 
	 * @Title: getRandomString
	 * @Description: 获取n位随机英文字符串:小写字母的ASC码97-122，大写字母的ASCII码65-90
	 * @param n
	 * @return
	 * @return String
	 */
	public static String getRandomString(int n) {

		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < n; i++) {
			int a = (int) (Math.random() * 57 + 65);
			// 90-97是非英文字母，所以需要去掉
			if (a > 90 && a < 97) {
				int b = a - 90;
				a = a - b;
			}
			char c = (char) a;
			sb.append(c);
		}
		return sb.toString();
	}

	/**
	 * 
	 * @Title: getRandomNumberAndCharacter
	 * @Description: 获取n位随机英文和数字字符串:小写字母的ASCII码97-122，大写字母的ASCII码65-90
	 *               数字ASCII码为48-57
	 * @param n
	 * @return
	 * @return String
	 */
	public static String getRandomNumberAndCharacter(int n) {
		StringBuffer sb = new StringBuffer();
		int b = 0;
		for (int i = 0; i < n; i++) {
			int a = (int) (Math.random() * 74 + 48);
			// 90-97是非英文字母，所以需要去掉
			if (a > 90 && a < 97) {
				b = a - 90;
				a = a - b;
			}
			// 57-65是非数字，所以需要过滤
			if (a > 57 && a < 65) {
				b = a - 57;
				a = a - b;
			}
			char c = (char) a;
			sb.append(c);
		}
		return sb.toString();
	}

	/**
	 * 
	 * @Title: getChinese
	 * @Description: 获取n个随机中文字符串 提示：Unicode字符中文编码从十六进制数4e00到十六进制数9fa5之间。
	 * @param str
	 * @return
	 * @return Boolean
	 * @throws UnsupportedEncodingException
	 */
	public static String getChinese(int n) {
		// 先把Unicode字符中文编码转换十六进制
		int start = Integer.valueOf("4e00", 16);
//		System.out.println(start);
		int end = Integer.valueOf("9fa5", 16);
//		System.out.println(end);
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < n; i++) {
			// 随机生成一个char，然后转成字符串
			char c = (char) (int) (Math.random() * (end - start) + start);
			sb.append(c);
		}
		return sb.toString();

	}

	/**
	 * 获取链接的后缀名
	 * 
	 * @return
	 */
	public static String parseSuffix(String url) {
		Pattern pattern = Pattern.compile("\\S*[?]\\S*");
		Matcher matcher = pattern.matcher(url);
		String[] spUrl = url.toString().split("/");
		int len = spUrl.length;
		String endUrl = spUrl[len - 1];
		if (matcher.find()) {
			String[] spEndUrl = endUrl.split("\\?");
			return spEndUrl[0].split("\\.")[1];
		}
		return endUrl.split("\\.")[1];
	}

	/**
	 * 
	 * @Title: readTxtFile
	 * @Description: 读取文本文件，io流读取
	 * @param filePath
	 * @param encoding
	 *            编码，默认用utf-8
	 * @return
	 * @throws IOException
	 * @return String
	 */
	public static String readTxtFile(String filePath, String encoding) throws IOException {
		long end = 0l;
		long start = System.currentTimeMillis();
		System.out.println("运行开始时间：" + start);
		try {
			File file = new File(filePath);
			if (file.isFile() && file.exists()) { // 判断文件是否存在
				InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式
				BufferedReader bufferedReader = new BufferedReader(read);
				String lineTxt = null;
				StringBuffer sb = new StringBuffer();
				while ((lineTxt = bufferedReader.readLine()) != null) {
					sb.append(lineTxt + "\n");
				}
				bufferedReader.close();
				read.close();
				end = System.currentTimeMillis();
				System.out.println("结束开始时间：" + end);
				System.out.println("花费时间：" + (end - start));
				return sb.toString();
			} else {
				throw new IOException("文件不存在");
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new IOException("文件不存在");
		}

	}

	/**
	 * 
	 * @Title: getPlaceholderValue
	 * @Description: 字符串截取，在指定的字符串中截取需要的字符串
	 * @param src
	 *            需要操作的字符串
	 * @param regex
	 *            正则表达式
	 * @return
	 * @return String
	 */
	public static String getPlaceholderValue(String src, String regex) {
		src = src.trim();
		String id = "";
		// 验证字符串是否为空，空的就不操作
		if (!isEmpty(src)) {
			return "字符串为空";
		}
		// 根据正则表达式匹配字符串
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(src);
		// 获取需要的字符串
		if (matcher.find()) {
			id = matcher.group(0);
		}
		return id;
	}

	/**
	 * 
	 * @Title: isNumber
	 * @Description: 判断字符串是否是数字，是的话转成int
	 * @param src
	 *            需要操作的字符串
	 * @param regex
	 *            正则表达式
	 * @return
	 * @return String
	 */
	public static int isNumber(String src, String regex) {
		src = src.trim();
		int score = 0;
		String str = "";
		// 验证字符串是否为空，空的就不操作
		if (!isEmpty(src.trim())) {
			return score;
		}
		// 根据正则表达式匹配字符串
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(src);
		// 获取需要的字符串
		if (matcher.find()) {
			str = matcher.group(0);
		}
		score = Integer.parseInt(str);
		return score;
	}

	/**
	 * 
	 * @Title: isNumber
	 * @Description: 判断数字，包括小数点
	 * @param source
	 * @return
	 * @return boolean
	 */
	public static boolean isNumber(String source) {
		boolean flag = false;
		if (!isEmpty(source)) {
			return flag;
		}
		Pattern pattern = Pattern.compile(NUMBER_POINT_REGEX);
		Matcher matcher = pattern.matcher(source);
		flag = matcher.matches();
		return flag;

	}

	/**
	 * 
	 * @Title: hasText
	 * @Description: 验证字符串是否为空
	 * @param str
	 * @return
	 * @return Boolean
	 */
	public static boolean hasText(String str) {
		boolean flag = false;

		// 判断字符串是否为null或""
		if (str == null || "".equals(str)) {
			return flag;
		}
		if (str.length() <= 0) {
			return flag;
		}
		// 根据正则表达式进行匹配
		Pattern pattern = Pattern.compile(BLANK_REGEX);
		Matcher matcher = pattern.matcher(str);
		// 首先判断字符串是否为空格（1-n个空格）
		if (matcher.matches()) {
			return flag;
		}
		flag = true;
		return flag;
	}

	/**
	 * 
	 * @Title: checkNameEnAndNo
	 * @Description: 判断是否有数字和字母
	 * @param name
	 *            被校验的字符
	 * @return
	 * @return boolean true代表符合
	 */
	public static boolean checkNameEnAndNo(String name) {
		boolean res = false;
		char[] cTemp = name.toCharArray();
		for (int i = 0; i < name.length(); i++) {
			if (isWord(cTemp[i])) {
				res = true;
				break;
			}
		}
		return res;
	}

	/**
	 * 
	 * @Title: isWord
	 * @Description: 校验某个字符是否是a-z、A-Z、_、0-9
	 * @param c
	 *            被校验的字符
	 * @return boolean true代表符合条件
	 */
	public static boolean isWord(char c) {
		String regEx = "[\\w]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher("" + c);
		return m.matches();
	}

	// 转换html
	public static String stringToHtml(String content) {
		if (isEmpty(content)) {
			System.out.println("替换前：" + content);
			try {
				if (content.contains("\n\r")) {
					content = content.replaceAll("\\\\n\\\\r", "\n");
				}
				if (content.contains("\r\n")) {
					content = content.replaceAll("\\\\r\\\\n", "\n");
				}
				if (content.contains("\r")) {
					content = content.replaceAll("\\\\r", "<br/>");
				}
				BufferedReader e = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(
						content.getBytes(Charset.forName("utf8"))), Charset.forName("utf8")));
				StringBuffer strbuf = new StringBuffer();
				String line;
				while ((line = e.readLine()) != null) {
					line = "<p>" + line + "</p>";
					strbuf.append(line + "\r\n");
				}
				System.out.println("替换后：" + strbuf.toString());
			} catch (IOException arg3) {
				arg3.printStackTrace();
			}
		}

		return content;
	}

	/**
	 * 
	 * @Title: toHtml
	 * @Description: 字符串转成html
	 * @param content
	 * @return
	 * @return String
	 */
	public static String toHtml(String content) {
		if (content.contains("\n\r")) {
			content = content.replaceAll("\\\\n\\\\r", "\n");
		}

		if (content.contains("\r\n")) {
			content = content.replaceAll("\\\\r\\\\n", "\n");
		}

		if (content.contains("\r")) {
			content = content.replaceAll("\\\\r", "<br/>");
		}

		content = "<p>" + content.replaceAll("\\n", "") + "</p>";
		return content;
	}
	/**
	 * 
	* @Title: isUrl
	* @Description: 判断是否为url
	* @param url
	* @return
	* @return boolean
	 */
	public static boolean isUrl(String url) {
		boolean flag = false;
		if (isEmpty(url)) {
			Pattern pattern = Pattern.compile(HTTP_URL_REGEX);
			Matcher matcher = pattern.matcher(url);
			flag = matcher.matches();
		}
		return flag;
	}

	/**
	 * 
	 * @Title: replaceHtml
	 * @Description: 替换掉HTML标签
	 * @param html
	 * @return
	 * @return String
	 */
	public static String replaceHtml(String html) {
		if (!isEmpty(html)) {
			return "";
		}
		String regEx = HTML_REGEX;
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(html);
		String s = m.replaceAll("");
		return s;
	}
	/**
	 * 
	* @Title: isMacthIp
	* @Description: 判断IP地址
	* @param ip
	* @return
	* @return boolean
	 */
	public static boolean isMacthIp(String ip) {
		if (ip != null && !ip.isEmpty()) {
			// 定义正则表达式
			String regex = IP_REGEX;
			// 判断ip地址是否与正则表达式匹配
			if (ip.matches(regex)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断身份证号码是否正确。
	 * 
	 * @param code
	 *            身份证号码。
	 * @return 如果身份证号码正确，则返回true，否则返回false。
	 */
	public static boolean isIdentityCode(String code) {

		if (!StringUtil.isEmpty(code)) {
			return false;
		}

		String birthDay = "";
		code = code.trim().toUpperCase();

		// 长度只有15和18两种情况
		if ((code.length() != IDENTITYCODE_OLD) && (code.length() != IDENTITYCODE_NEW)) {
			return false;
		}

		// 身份证号码必须为数字(18位的新身份证最后一位可以是x)
		Pattern pt = Pattern.compile(IDENTITY_CODE_REGEX);
		Matcher mt = pt.matcher(code);
		if (!mt.find()) {
			return false;
		}

		// 验证生日
		if (code.length() == IDENTITYCODE_OLD) {
			birthDay = "19" + code.substring(6, 12);
		} else {
			birthDay = code.substring(6, 14);
		}

		if (DateUtil.changeStringToDate(birthDay, "yyyyMMdd") == null) {
			return false;
		}

		// 最后一位校验码验证
		if (code.length() == IDENTITYCODE_NEW) {
			String lastNum = getCheckFlag(code.substring(IDENTITYCODE_NEW - 1));
			// check last digit
			if (!("" + code.charAt(IDENTITYCODE_NEW - 1)).toUpperCase().equals(lastNum)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * @Title: getCheckFlag
	 * @Description: 判断身份证最后一位x
	 * @param substring
	 * @return
	 * @return String
	 */
	private static String getCheckFlag(String substring) {
		if (substring.indexOf('x') != -1) { // 判断是不是有X
			substring = substring.replace("x", "X"); // 如果有X，就改成统一的大写X
		}
		return substring;
	}

	/**
	 * 
	 * @Title: isOdd
	 * @Description: 判断奇偶数
	 * @param a
	 * @return
	 * @return boolean
	 */
	public static boolean isOdd(int num) {
		if ((num & 1) != 1) { // 是奇数
			return true;
		}
		return false;
	}
	/**
	 * 
	* @Title: isEmpty
	* @Description: 判断collection是否为空
	* @param str
	* @return
	* @return boolean
	 */
	public static boolean isEmpty(Collection<?> str){
		return (str == null || str.isEmpty());
	}
	/**
	 * 
	* @Title: getRandom
	* @Description: 随机生成几位整数
	* @param size  指定位数
	* @return
	* @return int  随机数
	 */
	public static long getRandom(int size){
		//ThreadLocalRandom是JDK 7之后提供并发产生随机数，能够解决多个线程发生的竞争争夺。
		if(size < 2){
			return ThreadLocalRandom.current().nextInt(10);
		}
		//javaMath函数，等同于 10的size-1次方
		Double pow = Math.pow(10, size - 1);
		//去掉小数点
		int base = pow.intValue();
		//保证是size位数
		long number = base + ThreadLocalRandom.current().nextInt(base * 9);
		return number;

	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 10000; i++) {
			System.out.println(getRandom(8));
		}
	}
}
